/**
 * fshows.com
 * Copyright (C) 2013-2020 All Right Reserved
 */

package com.fshows.leshuapay.sdk.util;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.fshows.leshuapay.sdk.exception.LeshuaException;
import com.fshows.leshuapay.sdk.request.LeshuaBizRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;

import java.io.UnsupportedEncodingException;

/**
 * @author zhaoyi
 * @version SignUtil.java, v 0.1 2020-07-27 10:09 zhaoyi
 */
@Slf4j
public class SignUtil {

    /**
     * 默认版本
     */
    public static final String DEFAULT_VERSION = "2.0";

    /**
     * 签名前缀
     */
    public static final String SING_PREFIX = "lepos";

    /**
     * 默认字符集
     */
    public static final String DEFAULT_CHARSET = StringPool.UTF_8;

    /**
     * 获取签名值
     *
     * @param request
     * @return
     */
    public static <T> String getMerchantSign(LeshuaBizRequest<T> request, String privateKey) throws LeshuaException {
        String jsonData = JSON.toJSONString(request);
        StringBuffer sb = new StringBuffer(SING_PREFIX);
        sb.append(privateKey).append(jsonData);
        return doSign(sb.toString());
    }

    /**
     * 获取签名值
     *
     * @param request
     * @return
     */
    public static <T> String getSubsidySign(String request, String privateKey) throws LeshuaException {
        StringBuffer signStr = new StringBuffer();
        signStr.append(request).append(privateKey);
        String sign = "";
        try {
            sign = DigestUtils.md5Hex(signStr.toString().getBytes(DEFAULT_CHARSET));
        } catch (UnsupportedEncodingException e) {
            log.error("签名异常,ex={}", e);
            throw new LeshuaException("签名异常", e);
        }
        log.info("待签参数:{},签名值:{}", signStr, sign);
        return sign;
    }

    /**
     * 获取商户发票签名
     *
     * @param request
     * @return
     */
    public static <T> String getAgentVoiceSign(LeshuaBizRequest<T> request, String reqSerialNo, String privateKey) throws LeshuaException {
        String jsonData = JSON.toJSONString(request);
        StringBuffer sb = new StringBuffer();
        sb.append(privateKey).append(reqSerialNo).append(DEFAULT_VERSION).append(jsonData);
        return agentVoiceDoSign(sb.toString());
    }

    /**
     * 打款单签名
     *
     * @param requestJson
     * @param privateKey
     * @return
     * @throws LeshuaException
     */
    public static String getSettlementOrderSign(String requestJson, String privateKey) throws LeshuaException {
        StringBuffer sb = new StringBuffer(SING_PREFIX);
        sb.append(privateKey).append(requestJson);
        return doSign(sb.toString());
    }

    /**
     * 带有reqSerialNo和version的签名
     *
     * @param content
     * @param privateKey
     * @return
     * @throws LeshuaException
     */
    public static String getSignWithReqSerialNoAndVersion(String content, String privateKey, String reqSerialNo, String version) throws LeshuaException {
        StringBuilder sb = new StringBuilder();
        sb.append(privateKey);
        if (ObjectUtil.isNotNull(reqSerialNo)) {
            sb.append(reqSerialNo);
        }
        if (ObjectUtil.isNotNull(version)) {
            sb.append(version);
        }
        sb.append(content);
        try {
            return DigestUtils.md5Hex(sb.toString().getBytes(DEFAULT_CHARSET));
        } catch (Exception e) {
            log.error("签名异常,ex={}", e);
            throw new LeshuaException("签名异常", e);
        }
    }

    /**
     * 加签
     *
     * @param signStr
     * @return
     * @throws LeshuaException
     */
    public static String doSign(String signStr) throws LeshuaException {
        String sign = "";
        try {
            String md5 = DigestUtils.md5Hex(signStr.getBytes(DEFAULT_CHARSET));
            sign = Base64.encodeBase64String(md5.getBytes(DEFAULT_CHARSET));
        } catch (UnsupportedEncodingException e) {
            log.error("签名异常,ex={}", e);
            throw new LeshuaException("签名异常", e);
        }
        log.info("待签参数:{},签名值:{}", signStr, sign);
        return sign;
    }

    /**
     * 加签
     *
     * @param signStr
     * @return
     * @throws LeshuaException
     */
    public static String agentVoiceDoSign(String signStr) throws LeshuaException {
        String sign = "";
        try {
             sign = DigestUtils.md5Hex(signStr.getBytes(DEFAULT_CHARSET));
        } catch (UnsupportedEncodingException e) {
            log.error("签名异常,ex={}", e);
            throw new LeshuaException("签名异常", e);
        }
        log.info("待签参数:{},签名值:{}", signStr, sign);
        return sign;
    }
}
